package com.dmai.capacity.platform.gateway.service.impl;

import com.dmai.capacity.platform.common.utils.StringUtil;
import com.dmai.capacity.platform.gateway.chain.DistributedTokenBucketRateLimiter;
import com.dmai.capacity.platform.gateway.service.IRateLimitService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;

import javax.annotation.Resource;

/**
 * 根据应用限流
 */
@Slf4j
@Service
public class RateLimitServiceImpl implements IRateLimitService {
    // url匹配器
    private final AntPathMatcher pathMatcher = new AntPathMatcher();

    @Autowired
    private TokenStore tokenStore;


    @Resource
    private DistributedTokenBucketRateLimiter tokenBucketRateLimiter;

    /**
     * 1. 判断token是否有效 2. 如果token有对应clientId 2.1 判断clientId是否有效 2.2
     * 判断请求的服务service是否有效 2.3 判断clientId是否有权限访问service 3. 判断 clientId+service 每日限流
     *
     * @param reqUrl
     * @param accessToken
     * @return
     */
    @Override
    public boolean checkRateLimit(String reqUrl, String accessToken) {
        if (StringUtil.isNotBlank(accessToken)) {
            // 1. 按accessToken查找对应的clientId
            OAuth2Authentication oauth2Authentication = tokenStore.readAuthentication(accessToken);
            if (oauth2Authentication != null) {
                String clientId = oauth2Authentication.getOAuth2Request().getClientId();
                // 根据应用 url 限流
                // oauth_client if_limit 限流开关
                Integer flag = 1;

                if (1 == flag) {
                    boolean b = tokenBucketRateLimiter.tryAcquire(reqUrl, 8, 10, System.currentTimeMillis(), 1);
                    if (b) {
                        return false;
                    } else {
                        return true;
                    }
                }
            }
        }
        return false;
    }


}
